﻿#include "function_width_measure.h"


// Procedures 
// Local procedures 
void widthMeasure(HObject ho_image, HObject *ho_region_show, HTuple *hv_min_value,
	HTuple *hv_max_value, HTuple *hv_ret);

// Procedures 
// Local procedures 
void widthMeasure(HObject ho_image, HObject *ho_region_show, HTuple *hv_min_value,
	HTuple *hv_max_value, HTuple *hv_ret)
{

	// Local iconic variables
	HObject  ho_Region, ho_ConnectedRegions, ho_SelectedRegions;
	HObject  ho_RegionComplement, ho_ConnectedRegions1, ho_RegionLines;

	// Local control variables
	HTuple  hv_Area, hv_Row1, hv_SelectedRegionsColumn;
	HTuple  hv_Width, hv_Height, hv_Row, hv_ColumnBegin, hv_ColumnEnd;
	HTuple  hv_Indices;

	GenEmptyRegion(&(*ho_region_show));
	Threshold(ho_image, &ho_Region, 240, 255);
	Connection(ho_Region, &ho_ConnectedRegions);
	SelectShapeStd(ho_ConnectedRegions, &ho_SelectedRegions, "max_area", 70);
	Complement(ho_SelectedRegions, &ho_RegionComplement);
	Connection(ho_RegionComplement, &ho_ConnectedRegions1);
	SelectShapeStd(ho_ConnectedRegions1, &ho_SelectedRegions, "max_area", 70);
	AreaCenter(ho_SelectedRegions, &hv_Area, &hv_Row1, &hv_SelectedRegionsColumn);
	GetImageSize(ho_image, &hv_Width, &hv_Height);
	if (0 != (int(hv_SelectedRegionsColumn < (hv_Width / 2))))
	{
		GetRegionRuns(ho_SelectedRegions, &hv_Row, &hv_ColumnBegin, &hv_ColumnEnd);
		TupleSortIndex(hv_ColumnEnd, &hv_Indices);
		(*hv_min_value) = HTuple(hv_ColumnEnd[HTuple(hv_Indices[0])]);
		(*hv_max_value) = HTuple(hv_ColumnEnd[HTuple(hv_Indices[(hv_Indices.TupleLength()) - 1])]);
		GenRegionLine(&ho_RegionLines, HTuple(hv_Row[HTuple(hv_Indices[0])]), 0, HTuple(hv_Row[HTuple(hv_Indices[0])]),
			(*hv_min_value));
		Union2((*ho_region_show), ho_RegionLines, &(*ho_region_show));
		GenRegionLine(&ho_RegionLines, HTuple(hv_Row[HTuple(hv_Indices[(hv_Indices.TupleLength()) - 1])]),
			0, HTuple(hv_Row[HTuple(hv_Indices[(hv_Indices.TupleLength()) - 1])]), (*hv_max_value));
		Union2((*ho_region_show), ho_RegionLines, &(*ho_region_show));
	}
	else
	{
		GetRegionRuns(ho_SelectedRegions, &hv_Row, &hv_ColumnBegin, &hv_ColumnEnd);
		TupleSortIndex(hv_ColumnEnd, &hv_Indices);
		(*hv_max_value) = HTuple(hv_ColumnBegin[HTuple(hv_Indices[0])]);
		(*hv_min_value) = HTuple(hv_ColumnBegin[HTuple(hv_Indices[(hv_Indices.TupleLength()) - 1])]);
		GenRegionLine(&ho_RegionLines, HTuple(hv_Row[HTuple(hv_Indices[0])]), (*hv_max_value),
			HTuple(hv_Row[HTuple(hv_Indices[0])]), hv_Width - 1);
		Union2((*ho_region_show), ho_RegionLines, &(*ho_region_show));
		GenRegionLine(&ho_RegionLines, HTuple(hv_Row[HTuple(hv_Indices[(hv_Indices.TupleLength()) - 1])]),
			(*hv_min_value), HTuple(hv_Row[HTuple(hv_Indices[(hv_Indices.TupleLength()) - 1])]),
			hv_Width - 1);
		Union2((*ho_region_show), ho_RegionLines, &(*ho_region_show));
		(*hv_max_value) = hv_Width - (*hv_max_value);
		(*hv_min_value) = hv_Width - (*hv_min_value);

	}


	(*hv_ret) = 1;
	return;
}



FunctionWidthMeasure::FunctionWidthMeasure(QDialog* parent, QSettings* qsettings, QString section) : QDialog(parent)
{
    m_qsettings = qsettings;
    m_section = section;

    //m_model_image_path = QCoreApplication::applicationDirPath() + "/" + m_model_image_path;

    this->setWindowTitle(("Width Measure"));
    QRect desktop_rect = QApplication::desktop()->geometry();
    double ratio_x = desktop_rect.width()/1920.0;
    double ratio_y = desktop_rect.height()/1080.0;

    move(0,0);
    setFixedSize(1920*ratio_x,1010*ratio_y);

    m_view = new MyQGraphicsView(this);
	m_view->setGeometry(660 * ratio_x, 0, 1250 * ratio_x, 940 * ratio_y);

//    Row1=10;Column1=10;Row2=1000;Column2=1000;
//    m_view->setLinePose(10,10,Row2,Column2,Range);

    QSize control_size(150*ratio_x,40*ratio_y);

    QWidget* p = new QWidget(this);
    p->move(0*ratio_x,0*ratio_y);
    p->setFixedSize(600*ratio_x,800*ratio_y);

    QGridLayout *qgridLayout = new QGridLayout();
    p->setLayout(qgridLayout);

    int index = 0;

    QSize ButtonSize(220 * ratio_x, 40 * ratio_y);

  
    /*index++;
    m_qcombox_transition = new QComboBox();
    m_qcombox_transition->setFixedSize(control_size);
    m_qcombox_transition->addItem("从暗到明");
    m_qcombox_transition->addItem("从明到暗");
    qgridLayout->addWidget(m_qcombox_transition, index, 0);*/

    //index++;
   /* m_qlabel_detection_count = new QLabel();
    m_qlabel_detection_count->setText("Count");
    m_qlabel_detection_count->setFixedSize(control_size);
    qgridLayout->addWidget(m_qlabel_detection_count,index,0);
    m_qspinbox_detection_count = new QSpinBox();
    m_qspinbox_detection_count->setFixedSize(control_size);
    m_qspinbox_detection_count->setMinimum(1);
    m_qspinbox_detection_count->setMaximum(1000);
    qgridLayout->addWidget(m_qspinbox_detection_count, index, 1);

    index++;*/

//    m_qlabel_distance_standard = new QLabel();
//    m_qlabel_distance_standard->setText("standard");
//    m_qlabel_distance_standard->setFixedSize(control_size);
//    qgridLayout->addWidget(m_qlabel_distance_standard, index, 0);
//    m_qspinbox_distance_standard = new QSpinBox();
//    m_qspinbox_distance_standard->setFixedSize(control_size);
//    m_qspinbox_distance_standard->setMinimum(1);
//    m_qspinbox_distance_standard->setMaximum(10000);
//    qgridLayout->addWidget(m_qspinbox_distance_standard, index, 1);
//	index++;

	m_qlabel_1_min = new QLabel();
    m_qlabel_1_min->setText("Min");
	m_qlabel_1_min->setFixedSize(control_size);
	qgridLayout->addWidget(m_qlabel_1_min, index, 0);
	m_qspinbox_1_min = new QSpinBox();
	m_qspinbox_1_min->setFixedSize(control_size);
	m_qspinbox_1_min->setMinimum(1);
	m_qspinbox_1_min->setMaximum(10000);
	qgridLayout->addWidget(m_qspinbox_1_min, index, 1);
	index++;
	m_qlabel_1_max = new QLabel();
    m_qlabel_1_max->setText("Max");
	m_qlabel_1_max->setFixedSize(control_size);
	qgridLayout->addWidget(m_qlabel_1_max, index, 0);
	m_qspinbox_1_max = new QSpinBox();
	m_qspinbox_1_max->setFixedSize(control_size);
	m_qspinbox_1_max->setMinimum(1);
	m_qspinbox_1_max->setMaximum(10000);
	qgridLayout->addWidget(m_qspinbox_1_max, index, 1);
	index++;

	/*m_qlabel_2_min = new QLabel();
    m_qlabel_2_min->setText("2 Min");
	m_qlabel_2_min->setFixedSize(control_size);
	qgridLayout->addWidget(m_qlabel_2_min, index, 0);
	m_qspinbox_2_min = new QSpinBox();
	m_qspinbox_2_min->setFixedSize(control_size);
	m_qspinbox_2_min->setMinimum(1);
	m_qspinbox_2_min->setMaximum(10000);
	qgridLayout->addWidget(m_qspinbox_2_min, index, 1);
	index++;
	m_qlabel_2_max = new QLabel();
    m_qlabel_2_max->setText("2 Max");
	m_qlabel_2_max->setFixedSize(control_size);
	qgridLayout->addWidget(m_qlabel_2_max, index, 0);
	m_qspinbox_2_max = new QSpinBox();
	m_qspinbox_2_max->setFixedSize(control_size);
	m_qspinbox_2_max->setMinimum(1);
	m_qspinbox_2_max->setMaximum(10000);
	qgridLayout->addWidget(m_qspinbox_2_max, index, 1);

	index++;
	m_qlabel_3_min = new QLabel();
    m_qlabel_3_min->setText("3 Min");
	m_qlabel_3_min->setFixedSize(control_size);
	qgridLayout->addWidget(m_qlabel_3_min, index, 0);
	m_qspinbox_3_min = new QSpinBox();
	m_qspinbox_3_min->setFixedSize(control_size);
	m_qspinbox_3_min->setMinimum(1);
	m_qspinbox_3_min->setMaximum(10000);
	qgridLayout->addWidget(m_qspinbox_3_min, index, 1);
    index++;
    m_qlabel_3_max = new QLabel();
    m_qlabel_3_max->setText("3 Max");
    m_qlabel_3_max->setFixedSize(control_size);
    qgridLayout->addWidget(m_qlabel_3_max, index, 0);
    m_qspinbox_3_max = new QSpinBox();
    m_qspinbox_3_max->setFixedSize(control_size);
    m_qspinbox_3_max->setMinimum(1);
    m_qspinbox_3_max->setMaximum(10000);
    qgridLayout->addWidget(m_qspinbox_3_max, index, 1);

    index++;
    m_qlabel_4_min = new QLabel();
    m_qlabel_4_min->setText("4 Min");
    m_qlabel_4_min->setFixedSize(control_size);
    qgridLayout->addWidget(m_qlabel_4_min, index, 0);
    m_qspinbox_4_min = new QSpinBox();
    m_qspinbox_4_min->setFixedSize(control_size);
    m_qspinbox_4_min->setMinimum(1);
    m_qspinbox_4_min->setMaximum(10000);
    qgridLayout->addWidget(m_qspinbox_4_min, index, 1);

    index++;
    m_qlabel_4_max = new QLabel();
    m_qlabel_4_max->setText("4 Max");
    m_qlabel_4_max->setFixedSize(control_size);
    qgridLayout->addWidget(m_qlabel_4_max, index, 0);
    m_qspinbox_4_max = new QSpinBox();
    m_qspinbox_4_max->setFixedSize(control_size);
    m_qspinbox_4_max->setMinimum(1);
    m_qspinbox_4_max->setMaximum(10000);
    qgridLayout->addWidget(m_qspinbox_4_max, index, 1);

    index++;*/
    m_pushbutton_save_parameter = new QPushButton(this);
    m_pushbutton_save_parameter->setFixedSize(control_size);
    m_pushbutton_save_parameter->setText("Save");
    connect(m_pushbutton_save_parameter, &QPushButton::clicked, this, &FunctionWidthMeasure::saveParameter);
    qgridLayout->addWidget(m_pushbutton_save_parameter, index,0);

    index++;
	m_pushbutton_show_orign_image = new QPushButton(this);
	m_pushbutton_show_orign_image->setFixedSize(control_size);
    m_pushbutton_show_orign_image->setText("ShowOrign");
	connect(m_pushbutton_show_orign_image, &QPushButton::clicked, this, [=]() {
		QImage q_image = matToQImage(m_image);
		m_view->setImage(q_image, "");
		return true;
	});
	qgridLayout->addWidget(m_pushbutton_show_orign_image, index, 0);

	m_pushbutton_detection = new QPushButton(this);
	m_pushbutton_detection->setFixedSize(control_size);
    m_pushbutton_detection->setText("Detection");
	connect(m_pushbutton_detection, &QPushButton::clicked, this, &FunctionWidthMeasure::detectionImage);
	qgridLayout->addWidget(m_pushbutton_detection, index, 1);
    
    index++;
    m_pushbutton_return = new QPushButton(this);
    m_pushbutton_return->setFixedSize(control_size);
    m_pushbutton_return->setText("Exit");
    qgridLayout->addWidget(m_pushbutton_return, index, 0);
    connect(m_pushbutton_return, &QPushButton::clicked, this, [=]() {
        this->hide();
        });
    loadParameter();
}

FunctionWidthMeasure::~FunctionWidthMeasure()
{
    ;
}

bool FunctionWidthMeasure::detection( HObject image_in, QString& message)
{
    try
    {
		HTuple hv_min_value,hv_max_value, hv_ret;
		widthMeasure(image_in, &m_region_show, &hv_min_value, &hv_max_value, &hv_ret);
		

		int ret = hv_ret[0].I();
		
		if(ret>0)
		{
			double min_value = hv_min_value[0].D();
			double max_value = hv_max_value[0].D();

			if ( min_value < m_1_min )
			{
				message = "width min NG:"  + QString::number(min_value);
				return false;
			}
			if (max_value > m_1_max)
			{
				message = "width max NG :" + QString::number(max_value);
				return false;
			}
			else
			{
				message += "width min:"    + QString::number(min_value) + "width max:" + QString::number(max_value);
			}
			
			return true;
        }
        else
        {
            return false;
        }
    }
	catch (HException &HDevExpDefaultException)
	{
		message = HDevExpDefaultException.ErrorMessage();
		return false;
	}
  
    return true;
}

void FunctionWidthMeasure::detectionImage()
{
    if(m_image.empty())
    {
        QMessageBox::information(nullptr,"","no image");
        return;
    }

    QString message;
    HObject image = matToHImage(m_image);
    detection(image, message);

    Mat image_show = m_image.clone();
    if(image_show.empty())
    {
        QMessageBox::information(nullptr,"","no image");
        return;
    }
    draw(image_show, image_show);

    QImage q_image = matToQImage(image_show);

    m_view->setImage(q_image, message);
    
    }

void FunctionWidthMeasure::draw(Mat image_in,Mat& image_out)
{
    if(image_in.empty())
        return;
    if (image_in.channels() == 1)
	{
		cvtColor(image_in, image_in, COLOR_GRAY2BGR);
	}
	

	image_out = drawRegion(image_in, m_region_show, Scalar(0, 0, 255));
	GenEmptyRegion(&m_region_show);

	
}

void FunctionWidthMeasure::loadParameter()
{

	//m_detection_count = m_qsettings->value(m_section + "/" + "m_detection_count",1).toInt();
//	m_distance_standard = m_qsettings->value(m_section + "/" + "m_distance_standard",1).toInt();

	m_1_min = m_qsettings->value(m_section + "/" + "m_1_min").toInt();
	m_1_max = m_qsettings->value(m_section + "/" + "m_1_max").toInt();
	/*m_2_min = m_qsettings->value(m_section + "/" + "m_2_min").toInt();
	m_2_max = m_qsettings->value(m_section + "/" + "m_2_max").toInt();
	m_3_min = m_qsettings->value(m_section + "/" + "m_3_min").toInt();
	m_3_max = m_qsettings->value(m_section + "/" + "m_3_max").toInt();
	m_4_min = m_qsettings->value(m_section + "/" + "m_4_min").toInt();
	m_4_max = m_qsettings->value(m_section + "/" + "m_4_max").toInt();*/

    
    //m_qspinbox_detection_count->setValue(m_detection_count);
//    m_qspinbox_distance_standard->setValue(m_distance_standard);
    
    m_qspinbox_1_min->setValue(m_1_min);
	m_qspinbox_1_max->setValue(m_1_max);
	/*m_qspinbox_2_min->setValue(m_2_min);
	m_qspinbox_2_max->setValue(m_2_max);
	m_qspinbox_3_min->setValue(m_3_min);
	m_qspinbox_3_max->setValue(m_3_max);
	m_qspinbox_4_min->setValue(m_4_min);
	m_qspinbox_4_max->setValue(m_4_max);;*/
    return ;
}

void FunctionWidthMeasure::saveParameter()
{
   

    
	//m_detection_count = m_qspinbox_detection_count->value();
//	m_distance_standard = m_qspinbox_distance_standard->value();
	
	m_1_min = m_qspinbox_1_min->value();
	m_1_max = m_qspinbox_1_max->value();
	/*m_2_min = m_qspinbox_2_min->value();
	m_2_max = m_qspinbox_2_max->value();
	m_3_min = m_qspinbox_3_min->value();
	m_3_max = m_qspinbox_3_max->value();
    m_4_min = m_qspinbox_4_min->value();
    m_4_max  = m_qspinbox_4_max->value();*/

    //m_qsettings->setValue(m_section + "/" + "m_detection_count", m_detection_count);
//    m_qsettings->setValue(m_section + "/" + "m_distance_standard", m_distance_standard);
    
	m_qsettings->setValue(m_section + "/" + "m_1_min", m_1_min);
	m_qsettings->setValue(m_section + "/" + "m_1_max", m_1_max);
	/*m_qsettings->setValue(m_section + "/" + "m_2_min", m_2_min);
	m_qsettings->setValue(m_section + "/" + "m_2_max", m_2_max);
	m_qsettings->setValue(m_section + "/" + "m_3_min", m_3_min);
	m_qsettings->setValue(m_section + "/" + "m_3_max", m_3_max);
	m_qsettings->setValue(m_section + "/" + "m_4_min", m_4_min);
    m_qsettings->setValue(m_section + "/" + "m_4_max", m_4_max);*/

    
    return;
}

bool FunctionWidthMeasure::showDialog()
{
    QImage q_image = matToQImage(m_image);
    m_view->setImage(q_image, "");
   
    return true;
}


